<?php
/**
 *
 *
 * @author Zeon <scplay@gmail.com>
 * @date 2018/11/13 14:47
 * @copyright PanxSoft Inc.
 */

namespace App\Http\Controllers\Api\V1\App\Common;

use App\Http\Controllers\ApiController;
use App\Http\Requests\Common\LogisticTrace\LogisticTraceSubscribeRequest;
use App\Jobs\AutoSignOrder;
use App\Models\Order\Order;
use App\Models\Order\OrderAutoSign;
use App\Services\Kdniao\Kdniao;
use App\Services\Kdniao\MockData;
use Illuminate\Http\Request;

/**
 * 物流查询
 */
class LogisticTraceController extends ApiController
{
    /**
     * @param Request $request
     *
     * @return array|\Illuminate\Http\Response
     * @throws \Exception
     */
    public function index(Request $request)
    {
        $shipper_code = $request->shipper_code;
        $logistic_code = $request->logistic_code;

        $this->checkIsTrue(($logistic_code && $shipper_code), trans('order.logistic'));

        $logistic_trace = (new Kdniao)->queryTraces($shipper_code, $logistic_code);

        // reverse timeline
        $logistic_trace['Traces'] = array_reverse($logistic_trace['Traces']);

        return $this->response(compact('logistic_trace'));
    }

    /**
     * 物流信息订阅
     *
     * @param LogisticTraceSubscribeRequest $request
     *
     * @return array|\Illuminate\Http\Response
     * @throws \Exception
     */
    public function subscribe(LogisticTraceSubscribeRequest $request)
    {
        $subscribed = (new Kdniao)->subscribeTraces(
            $request->shipper_code,
            $request->logistic_code,
            $request->order_id
        );

        return $this->response(compact('subscribed'));
    }

    /**
     * 处理物流订阅回调 - 签收订单
     *
     * @param Request $request
     * @return array|\Illuminate\Http\Response
     *
     * @throws \Exception
     */
    public function notify(Request $request)
    {
        /**
         * @see MockData::notifyData()
         */
        $data = json_decode($request->RequestData, true);
            $this->checkIsTrue($data, 'RequestData JSON parse failed! '. json_last_error_msg());

        $order_id = data_get($data, 'Data.0.OrderCode');
            $this->checkIsTrue($order_id, 'RequestData OrderCode not found!');

        $trace_state = data_get($data, 'Data.0.State');
            $this->checkIsTrue($trace_state, 'RequestData Logistic State not found!');
            $this->checkIsTrue((string) $trace_state === Kdniao::LOGISTIC_STATE_RECEIVED, 'RequestData Logistic State not received!');

        /** @var Order $order */
        $order = (new Order)->find($order_id);
            $this->checkItemExist($order, "Order[$order_id]");
            $this->checkUnless($order->orderAutoSign, "Order[$order_id] auto sign record already exist");

        $should_sign_at = now()->addMinute(OrderAutoSign::getDelayMinute());
        /** @var OrderAutoSign $created */
        $created = $order->orderAutoSign()->create(compact('should_sign_at'));

        AutoSignOrder::dispatch($created)->delay($should_sign_at);

        return $this->response(compact('created'));
    }
}